<?php
/**
 * Instance d'interface PDO
 * @author : Joseph Lemoine - lemoine.joseph@gmail.com
 * @version : 6
*/
class Sql extends PDO {

    /**
     * Stockage de l'objet PDO instancié
     * @var:	array	(dnsBase => Objet)
     * @static
     */
    public static $_instance = array();

    /**
     * Compteur de requète pour le débug
     * @var:	int
     * @static
     */
    public static $_benchmark = 0;

    /**
     * Listing des requètes pour le débug
     * @var:	string
     * @static
     */
    public static $_history = "";

    /**
     * constructeur de class. Privé pour éviter les accès extérieur
     * @return: $this;
     */
    public function __construct($bdd, $user, $pass){
		return parent::__construct($bdd, $user, $pass);
    }

    /**
     * Renvois de l'instance PDO et init si requis avec gestion des erreurs
     * @param	string	$alias	Alias de base de donnée
     * @return	obj instance PDO
    */
    public static function getInstance($alias = "") {
    	/* Création de l'alias */
    	$alias = empty($alias) ? DEF_BASE : $alias;
	    $alias = DEBUG ? $alias."_DEBUG" : $alias;
	    $alias = strtoupper($alias);

		/* définition des codes d'accès à la base */
		$base_name = constant($alias . "_BASE_NAME");
		$base_host = constant($alias . "_BASE_HOST");
		$base_user = constant($alias . "_BASE_USER");
		$base_pwd = constant($alias . "_BASE_PWD");

		/* Définition du DNS */
		$dns = "mysql:dbname=" . $base_name . ";host=" . $base_host . ";";

		/* Si la base n'à pas encore été instancié, on la crée */
		if(!self::$_instance[$dns]) {

		    try {
				/* Création de la base PDO */
				self::$_instance[$dns] = new Sql($dns, $base_user, $base_pwd);
				/* On force l'utilisation de l'UTF-8 */
				self::$_instance[$dns]->exec('SET NAMES utf8');
		    }catch(PDOException $e) {
				echo "Connexion échouée : " . $e->getMessage();
				exit();
		    }

		}

		return self::$_instance[$dns];
    }

    /**
	 * Exécute une requète en surchargeant PDO
	 * @param:	string	$statement	Requète SQL à exécuter
	 * @return:	array
     */
    public function query($statement){
    	if(DEBUG)
    		self::$_benchmark++;

		$result = parent::query($statement) or die(self::displayCrash($statement, parent::errorInfo()));

		return $result;
    }

    /**
     * Alias pour faire un fatch all après une requète sans créer de DAO
     * @param:	string	$query Requète SQL à exécuter
     * @param:	string	$alias	Nom de la base de donnée à appeler
     * @return:	array	Résultat de la requète dans un array
     * @static
     */
	public static function run($query, $alias = ""){
		return self::getInstance($alias)->query($query)->fetchAll();
    }

    /**
     * Affiche les erreurs de requètes
     * @param	string	$requete	Requète SQL
     * @param	array	$erreur
     * @static
     */
    private static function displayCrash($requete, $erreur = array()){
		$send .= '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">'
			. '<html>'
				. '<head>'
					. '<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />'
					. '<title>Template</title>'
				. '</head>'
				. '<body>'
					. '<div id="debugbox" style="display: block;">'
						. '<h4>Information de debug : <span class="warning">Erreur SQL !</span></h4>'
						. '<center>'
							. '<p class="text">' . $requete . '</p>'
						. '</center>'
						. '<table width="100%" align="center" cellspading="4" cellspacing="0" border="0">'
							. '<tr>'
								. '<td width="120">Code erreur SQL</td><td width="20"> : </td><td>' . $erreur[0] . '</td>'
							. '</tr>'
							. '<tr>'
								. '<td width="120">Code erreur Driver</td><td width="20"> : </td><td>' . $erreur[1] . '</td>'
							. '</tr>'
							. '<tr>'
								. '<td width="120" valign="top">Message d\'erreur</td><td  width="20" valign="top"> : </td><td>' . $erreur[2] . '</td>'
							. '</tr>'
						. '</table>'
					. '</div>';

		// Ecriture de la stucture du footer
		$send .= '</body>'
			. '</html>';
		echo $send;
		exit();
    }

    /**
     * Destructeur de class, essentiellement utilisé pour du DEBUG
     * @author	Joseph Lemoine - lemoine.joseph@gmail.com
     * @param	VOID
     * @return	VOID
     * @access	Public
     */
    public function  __destruct() {
    	/* Affichage des statistiques */
		if(DEBUG){
		    echo "<div id='debugSwitch'
		    		OnClick='javascript:$(this).next(\"div\").fadeIn(\"fast\");'
		    		style='bottom: 0px; left: 0px; position: fixed;'>
		    		<img src='../www-ressources/images/firebug-40x40.png'/>
		    </div>
		    <div style='display: none; width: 90%; min-height: 90%; margin: 4%;
			    border: 1px solid white; background: rgba(0,0,0,0.8);
			    position: absolute; top: 0px; padding: 1%;
			    color: white;'
			    OnClick='javascript:$(this).fadeOut(\"fast\");'>
				Nombre de requète effectués :
				".self::$_benchmark."
		    </div>";
		}
    }

}
?>